// app/business/api/common/gas_estimator.go
package common

import (
	"context"
	"fmt"
	"math/big"
	"strings"
	"time"

	"private-domain-overseas-service/pkg/constant"

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/accounts/abi"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

// WeiToEth converts wei to ETH format
func WeiToEth(wei *big.Int) string {
	eth := new(big.Float).SetInt(wei)
	eth = eth.Quo(eth, big.NewFloat(1e18)) // 1 ETH = 1e18 wei
	return eth.Text('f', 18)
}

func EstimateGasFee(client *ethclient.Client, hzbContractAddress string, from, to common.Address, amount *big.Int) (*constant.GasEstimate, error) {
	maxRetries := 3
	var lastErr error

	for i := 0; i < maxRetries; i++ {
		// 1. 解析 HZB 合约 ABI
		hzbABI, err := abi.JSON(strings.NewReader(constant.HzbABI))
		if err != nil {
			lastErr = fmt.Errorf("解析 HZB ABI 失败: %v", err)
			continue
		}

		// 2. 获取 Gas Price
		gasPrice, err := client.SuggestGasPrice(context.Background())
		if err != nil {
			lastErr = fmt.Errorf("获取 Gas Price 失败: %v", err)
			if strings.Contains(err.Error(), "EOF") {
				time.Sleep(time.Second * time.Duration(i+1))
				continue
			}
			return nil, lastErr
		}

		// 3. 估算 Gas Limit
		data, err := hzbABI.Pack("transfer", to, amount)
		if err != nil {
			lastErr = fmt.Errorf("构造转账数据失败: %v", err)
			return nil, lastErr
		}

		contractAddr := common.HexToAddress(hzbContractAddress)
		msg := ethereum.CallMsg{
			From:  from,
			To:    &contractAddr,
			Value: big.NewInt(0),
			Data:  data,
		}

		var gasLimitUint64 uint64
		gasLimitUint64, err = client.EstimateGas(context.Background(), msg)
		if err != nil {
			lastErr = fmt.Errorf("估算 Gas Limit 失败: %v", err)
			if strings.Contains(err.Error(), "EOF") {
				time.Sleep(time.Second * time.Duration(i+1))
				continue
			}
			// 如果估算失败，使用默认值
			gasLimitUint64 = 100000 // 设置一个较高的默认值
			fmt.Printf("Gas 估算失败，使用默认值: %d\n", gasLimitUint64)
		}

		gasLimit := new(big.Int).SetUint64(gasLimitUint64)

		// 增加 20% 缓冲
		gasLimit = new(big.Int).Mul(gasLimit, big.NewInt(120))
		gasLimit = new(big.Int).Div(gasLimit, big.NewInt(100))

		// 4. 计算总 Gas 费用
		gasFee := new(big.Int).Mul(gasPrice, gasLimit)

		// 5. 转换为 HZB 等值（假设 1 ETH = 2000 HZB）
		ethToHzbRate := big.NewInt(2000 * 100)
		gasFeeHzb := new(big.Int).Div(
			new(big.Int).Mul(gasFee, ethToHzbRate),
			big.NewInt(1e18), // ETH 单位为 wei
		)

		return &constant.GasEstimate{
			GasPrice:     gasPrice,     // 当前网络建议的 Gas 价格
			GasLimit:     gasLimit,     // 估算的 Gas 限制值，包含 20% 的缓冲
			GasFee:       gasFee,       // 交易的总 Gas 费用 (单位: wei)
			GasFeeHzb:    gasFeeHzb,    // 交易的总 Gas 费用，按 HZB 等值计算
			EthToHzbRate: ethToHzbRate, // ETH 到 HZB 的汇率
		}, nil
	}

	return nil, fmt.Errorf("估算 Gas 费用失败，已重试 %d 次，最后错误: %v", maxRetries, lastErr)
}
